package com.TanNgee.registry.zk;

import com.TanNgee.enums.RpcErrorMessageEnum;
import com.TanNgee.excpetion.RpcException;
import com.TanNgee.extension.ExtensionLoader;
import com.TanNgee.loadbalance.LoadBalance;
import com.TanNgee.registry.ServiceDiscovery;
import com.TanNgee.registry.zk.util.CuratorUtils;
import com.TanNgee.remoting.dto.RpcRequest;
import com.TanNgee.utils.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.curator.framework.CuratorFramework;

import java.net.InetSocketAddress;
import java.util.List;

/**
 * 服务发现是实现类
 *
 * @author 陈毅
 * @create 2022/3/21 0:36
 */
@Slf4j
public class ZkServiceDiscoveryImpl implements ServiceDiscovery {

    private final LoadBalance loadBalance;

    public ZkServiceDiscoveryImpl() {
        this.loadBalance = ExtensionLoader.getExtensionLoader(LoadBalance.class).getExtension("loadBalance");
    }

    @Override
    /**
     * 从Zookeeper 上获取服务地址
     */
    public InetSocketAddress lookupService(RpcRequest rpcRequest) {

        String rpcServiceName = rpcRequest.getRpcServiceName();
        CuratorFramework zkClient = CuratorUtils.getZkClient();

        // 首先获取所有的可服务节点
        List<String> serviceUrlList = CuratorUtils.getChildrenNodes(zkClient, rpcServiceName);

        if (CollectionUtil.isEmpty(serviceUrlList)) {
            throw new RpcException(RpcErrorMessageEnum.SERVICE_CAN_NOT_BE_FOUND, rpcServiceName);
        }

        // 通过负载均衡策略 寻找合适的节点地址
        String targetServiceUrl = loadBalance.selectServiceAddress(serviceUrlList, rpcRequest);


        log.info("Successfully found the service address:[{}]", targetServiceUrl);
        String[] socketAddressArray = targetServiceUrl.split(":");


        String host = socketAddressArray[0];
        int port = Integer.parseInt(socketAddressArray[1]);

        // 返回服务地址
        return new InetSocketAddress(host, port);
    }
}
